var JWEIQI = {};

JWEIQI.kindGo = 0;
JWEIQI.kindFive = 1;
JWEIQI.kindSix = 2;
JWEIQI.stoneEmpty = 0;
JWEIQI.stoneBlack = 1;
JWEIQI.stoneWhite = 2;
JWEIQI.playerHuman = 0;
JWEIQI.playerBot = 1;

//region:引擎

JWEIQI.Game = function (kind, size) {
    this.kind = kind;
    this.size = size;
    var board = [];
    board.length = size;
    for (var i = 0; i < size; i++) {
        var col = [];
        col.length = size;
        for (var j = 0; j < size; j++) {
            col[j] = JWEIQI.stoneEmpty;
        }
        board[i] = col;
    }
    this.currentBoard = board;
    this.moves = [];

    this.getStoneForMove = function (index) {
        if (this.kind === JWEIQI.kindFive) {
            return index % 2 === 0 ? JWEIQI.stoneBlack : JWEIQI.stoneWhite;
        }
        else {
            throw { name: "NotSupported" };
        }
    };
    
    this.getNextStone = function () {
        return this.getStoneForMove(this.moves.length);
    };
    
    this.getLastStone = function () {
        return this.getStoneForMove(this.moves.length - 1);
    };
    
    this.playMove = function (move) {
        if (move !== null) {
            if (this.kind === JWEIQI.kindFive) {
                this.currentBoard[move.x][move.y] = this.getNextStone();
            }
            else {
                throw { name: "NotSupported" };
            }
        }
        this.moves.push(move);
    };

    this.checkMoveLegality = function (move) {
        if (this.currentBoard[move.x][move.y] === JWEIQI.stoneEmpty) {
            if (this.kind === JWEIQI.kindFive) {
                return true;
            }
            else {
                throw { name: "NotSupported" };
            }
        }
        else {
            return false;
        }
    };
    
    this.tryPlayMove = function (move) {
        if (this.checkMoveLegality(move)) {
            this.playMove(move);
            return true;
        }
        else {
            return false;
        }
    };
};

JWEIQI.Node = function (x, y) {
    this.update = function (val) {
        
    };
    this.getWinRate = function () {
        
    };
};

JWEIQI.Engine = function () {
    this.getBestChild = function (root) {
        
    };
    this.uctSelect = function (node) {
        
    };
    this.playSimulation = function (n) {
        
    };
    this.uctSearch = function (numsim) {
        
    };
    this.makeRandomMove = function () {
        
    };
    this.playRandomMove = function () {
        
    };
    this.copyStateFrom = function (b) {
        
    };
    this.createChildren = function (parent) {
        
    };
};

//endregion

JWEIQI.context = {
    game: new JWEIQI.Game(JWEIQI.kindFive, 19),
    blackPlayer: JWEIQI.playerHuman,
    whitePlayer: JWEIQI.playerBot
};

JWEIQI.getElementPositionInPage = function (element) {
    var x = 0, y = 0;
    var n = element;
    if (n === null) {
        throw { name: "CannotGet" };
    }
    for (var i = 0; i < 64; i++) {
        x += n.offsetLeft;
        y += n.offsetTop;
        n = n.offsetParent;
        if (n === null) {
            return [x, y];
        }
    }
    throw { name: "Overflow" };
};

JWEIQI.getEventPosInBoardOverlay = function (e) {
    var elementPos = JWEIQI.getElementPositionInPage(document.getElementById("boardOverlay"));
    var mouseX = e.pageX - elementPos[0];
    var mouseY = e.pageY - elementPos[1];
    return [mouseX, mouseY];
};

JWEIQI.init = function () {
    JWEIQI.context.game = new JWEIQI.Game(JWEIQI.context.game.kind, JWEIQI.context.game.size);
    JWEIQI.redraw();
};

JWEIQI.initBySize = function (size) {
    JWEIQI.context.game = new JWEIQI.Game(JWEIQI.context.game.kind, size);
    JWEIQI.redraw();
};

JWEIQI.redraw = function () {
    //整体定位与排版
    (function () {
        var position = 0.333;
        var minMargin = 25;
        var windowHeight = $(window).height();
        $("#content").removeClass().addClass(windowHeight > 620 ? "bigLayout" : "smallLayout");
        var contentHeight = $("#content").height();
        $("#middleContent").css("width", contentHeight).css("height", contentHeight);
        $("#leftVisual,#rightVisual").css("margin-top", (contentHeight - 150) / 2);
        $("#content").css("margin-top", windowHeight > contentHeight + minMargin / position ? (windowHeight - contentHeight) * position : minMargin);
    })();

    //绘制棋盘格子
    (function () {
        var gridOpacity = 0.333;
        var game = JWEIQI.context.game;
        var n = game.size - 1; //格子数
        var totalLength = $("#boardContent").width();
        var unitLength = totalLength / game.size;
        var offset = Math.round(unitLength / 2);
        var length = Math.round(totalLength - unitLength);
        var s = '<table class="boardGrid" style="position:absolute;left:' + offset +
            'px;top:' + offset + 'px;width:' + length + 'px;height:' + length + 'px;">';
        for (var i = 0; i < n; i++) {
            s += '<tr>';
            for (var j = 0; j < n; j++) {
                s += '<td></td>';
            }
            s += '</tr>';
        }
        s += '</table>';
        $("#boardGridContainer").html(s);

        //边线较粗，所以要在这里额外绘制。注意：不能直接设表格边框为粗，那样的话会使单元格的长度不再平均分配。
        $(
            '<div class="boardGridBorder" style="position:absolute;left:' + (offset - 1) +
            'px;top:' + (offset - 1) + 'px;width:' + length + 'px;height:' + length + 'px;"></div>'
        ).css("opacity", gridOpacity).appendTo("#boardGridContainer");
        $(".boardGrid").css("opacity", gridOpacity);
    })();

    //重新画棋子
    (function () {
        var game = JWEIQI.context.game;
        $("#boardStoneContainer").empty();
        for (var i = 0; i < game.moves.length; i++) {
            JWEIQI.drawMove(game.getStoneForMove(i), game.moves[i]);
        }
    })();
};

JWEIQI.drawMove = function (stone, move) {
    var size = JWEIQI.context.game.size;
    var totalLength = $("#boardContent").width();
    var unitLength = totalLength / size;
    var offset = unitLength / 2;
    var drawX = offset + move.x * unitLength;
    var drawY = offset + move.y * unitLength;
    var stoneColorName;
    var stoneSize;
    var displayFactor;
    var displaySize;
    if (stone === JWEIQI.stoneBlack) {
        stoneColorName = "black";
    }
    else if (stone === JWEIQI.stoneWhite) {
        stoneColorName = "white";
    }
    else {
        throw { name: "NotSupported" };
    }
    if ($("#content").hasClass("smallLayout")) {
        displayFactor = 0.75;
    }
    else {
        displayFactor = 1;
    }
    if (size >= 19) {
        stoneSize = 39;
        displaySize = 39 * 19 / size * displayFactor;
    }
    else if (size >= 9) {
        stoneSize = 81;
        displaySize = 81 * 9 / size * displayFactor;
    }
    else {
        stoneSize = 147;
        displaySize = 147 * 5 / size * displayFactor;
    }
    var left = (drawX - Math.floor(displaySize / 2) - 1);
    var top = (drawY - Math.floor(displaySize / 2) - 1);
    var symbolFactor = 0.08;
    $("#boardStoneContainer").append('<img src="' + stoneColorName + '-stone-' + stoneSize + '.png" alt="" style="position:absolute;left:' + left + 'px;top:' + top + 'px;width:' + displaySize + 'px;height:' + displaySize + 'px;" />');
    $("#boardLastMoveSymbol").css("left", left + displaySize * symbolFactor).css("top", top + displaySize * symbolFactor).css("width", displaySize - 2 - 2 * displaySize * symbolFactor).css("height", displaySize - 2 - 2 * displaySize * symbolFactor);
};

$(document).ready(function () {
    $("#boardOverlay").css("opacity", 0);
    $(".buttonBackground").css("opacity", 0.667);
    $("#boardLastMoveSymbol").css("opacity", 0.333);

    $(window).resize(JWEIQI.redraw);

    JWEIQI.redraw();

    $("#boardOverlay").mousedown(function (e) {
        e.preventDefault();
        var pos = JWEIQI.getEventPosInBoardOverlay(e);
        var totalLength = $("#boardContent").width();
        var unitLength = totalLength / JWEIQI.context.game.size;
        var x = Math.floor(pos[0] / unitLength);
        var y = Math.floor(pos[1] / unitLength);
        var newMove = { x: x, y: y };
        if (JWEIQI.context.game.tryPlayMove(newMove)) {
            JWEIQI.drawMove(JWEIQI.context.game.getLastStone(), newMove);
        }
    });
    $("#boardOverlay").mouseup(function (e) {
        e.preventDefault();
    });
    $("#boardOverlay").mousemove(function (e) {
        e.preventDefault();
    });
});